<template>
  <div class="dicom-volume-page">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <div class="toolbar-left">
        <h2 class="page-title">体数据加载 (MPR + VTK 3D)</h2>
      </div>
      <div class="toolbar-right">
        <div class="connection-status">
          <span class="status-indicator" :class="{ 'connected': orthancConnected, 'disconnected': !orthancConnected }">
            {{ orthancConnected ? '🟢' : '🔴' }}
          </span>
          <span class="status-text">
            {{ orthancConnected ? 'Orthanc已连接' : 'Orthanc未连接' }}
          </span>
        </div>
        
        <div class="volume-info" v-if="volumeData">
          <span class="info-item">{{ volumeData.dimensions.join(' × ') }}</span>
          <span class="info-item">{{ volumeData.slices }} 层</span>
          <span class="info-item">{{ formatFileSize(volumeData.totalSize) }}</span>
        </div>
        
        <!-- 系列选择 -->
        <select v-model="selectedSeriesId" class="series-select-toolbar" :disabled="loading">
          <option value="">选择系列</option>
          <option v-for="series in availableSeries" :key="series.id" :value="series.id">
            {{ series.MainDicomTags?.SeriesDescription || series.id }}
            ({{ series.Instances?.length || 0 }} 层)
          </option>
        </select>
        
        <button 
          class="load-btn" 
          @click="loadVolumeData" 
          :disabled="!orthancConnected || loading || !selectedSeriesId"
        >
          {{ loading ? '加载中...' : '加载体数据' }}
        </button>
        
        <button 
          class="reset-btn" 
          @click="resetAllViews" 
          :disabled="!volumeData"
        >
          重置视图
        </button>
      </div>
    </div>

    <!-- 加载进度 -->
    <div class="load-progress-bar" v-if="loading">
              <div class="progress-fill" :style="{ width: loadProgress + '%' }"></div>
      <div class="progress-text">{{ loadProgress.toFixed(0) }}% - {{ loadingStatus }}</div>
        </div>
        
    <!-- 主要内容区域：4宫格视图 -->
    <div class="main-content">
        <div v-if="!volumeData" class="empty-viewer">
          <div class="empty-content">
            <div class="empty-icon">🧊</div>
            <div class="empty-title">请加载体数据</div>
          <div class="empty-subtitle">选择一个系列并点击"加载体数据"按钮</div>
          </div>
        </div>
        
      <div v-else class="four-view-grid">
        <!-- 轴位视图 (左上) -->
            <div class="viewport axial-view">
              <div class="viewport-header">
                <h4>轴位 (Axial)</h4>
                <span class="slice-info">{{ currentSlices.axial + 1 }} / {{ volumeData.dimensions[2] }}</span>
              </div>
              <div class="viewport-content" ref="axialViewport">
                <canvas 
                  ref="axialCanvas" 
                  class="dicom-canvas"
              @wheel.prevent="onWheel('axial', $event)"
              @mousedown="onMouseDown($event)"
                  @mousemove="onMouseMove('axial', $event)"
              @mouseup="onMouseUp($event)"
                ></canvas>
                <div class="viewport-overlay">
                  <div class="orientation-labels">
                    <span class="label-top">A</span>
                    <span class="label-bottom">P</span>
                    <span class="label-left">R</span>
                    <span class="label-right">L</span>
                  </div>
                </div>
              </div>
          <div class="slice-slider-container">
            <input 
              v-model.number="currentSlices.axial" 
              type="range" 
              :min="0" 
              :max="volumeData.dimensions[2] - 1"
              class="slice-slider"
            >
          </div>
            </div>
            
        <!-- 冠状视图 (右上) -->
            <div class="viewport coronal-view">
              <div class="viewport-header">
                <h4>冠状 (Coronal)</h4>
                <span class="slice-info">{{ currentSlices.coronal + 1 }} / {{ volumeData.dimensions[1] }}</span>
              </div>
              <div class="viewport-content" ref="coronalViewport">
                <canvas 
                  ref="coronalCanvas" 
                  class="dicom-canvas"
              @wheel.prevent="onWheel('coronal', $event)"
              @mousedown="onMouseDown($event)"
                  @mousemove="onMouseMove('coronal', $event)"
              @mouseup="onMouseUp($event)"
                ></canvas>
                <div class="viewport-overlay">
                  <div class="orientation-labels">
                    <span class="label-top">S</span>
                    <span class="label-bottom">I</span>
                    <span class="label-left">R</span>
                    <span class="label-right">L</span>
                  </div>
                </div>
              </div>
          <div class="slice-slider-container">
            <input 
              v-model.number="currentSlices.coronal" 
              type="range" 
              :min="0" 
              :max="volumeData.dimensions[1] - 1"
              class="slice-slider"
            >
          </div>
            </div>
            
        <!-- 矢状视图 (左下) -->
            <div class="viewport sagittal-view">
              <div class="viewport-header">
                <h4>矢状 (Sagittal)</h4>
                <span class="slice-info">{{ currentSlices.sagittal + 1 }} / {{ volumeData.dimensions[0] }}</span>
              </div>
              <div class="viewport-content" ref="sagittalViewport">
                <canvas 
                  ref="sagittalCanvas" 
                  class="dicom-canvas"
              @wheel.prevent="onWheel('sagittal', $event)"
              @mousedown="onMouseDown($event)"
                  @mousemove="onMouseMove('sagittal', $event)"
              @mouseup="onMouseUp($event)"
                ></canvas>
                <div class="viewport-overlay">
                  <div class="orientation-labels">
                    <span class="label-top">S</span>
                    <span class="label-bottom">I</span>
                    <span class="label-left">A</span>
                    <span class="label-right">P</span>
                  </div>
                </div>
              </div>
          <div class="slice-slider-container">
            <input 
              v-model.number="currentSlices.sagittal" 
              type="range" 
              :min="0" 
              :max="volumeData.dimensions[0] - 1"
              class="slice-slider"
            >
          </div>
            </div>
            
        <!-- VTK 3D视图 (右下) -->
        <div class="viewport vtk-3d-view">
              <div class="viewport-header">
            <h4>VTK 3D 模型</h4>
                <div class="view-controls">
              <button @click="reset3DView" class="control-btn">重置</button>
              <button @click="toggle3DRotation" class="control-btn" :class="{ 'active': autoRotate }">
                {{ autoRotate ? '停止旋转' : '自动旋转' }}
              </button>
                </div>
              </div>
          <div class="viewport-content" ref="vtkViewport">
            <!-- VTK渲染容器 -->
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
import { orthancService } from '@/services/orthanc.service'

/**
 * VTK.js 依赖已移除
 * 
 * 说明: 由于 @kitware/vtk.js 在浏览器环境中存在兼容性问题（xmlbuilder2 依赖），
 * 已将其从项目中移除。如需 3D 体渲染功能，建议：
 * 1. 使用 Cornerstone3D 的原生 Volume 渲染功能
 * 2. 或者单独配置 vtk.js 的浏览器兼容版本
 * 
 * 当前页面功能已禁用，仅保留界面结构作为参考。
 */

// VTK.js 导入已注释，避免依赖错误
// import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow'
// import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer'
// ... 其他 vtk.js 导入已移除

// 体数据接口
interface VolumeData {
  dimensions: [number, number, number]
  spacing: [number, number, number]
  origin: [number, number, number]
  slices: number
  totalSize: number
  imageData: ImageData[]
  scalarData?: Uint8Array | Float32Array // 存储原始标量数据用于VTK
}

// 响应式数据
const orthancConnected = ref(false)
const loading = ref(false)
const loadProgress = ref(0)
const loadingStatus = ref('')
const availableSeries = ref<any[]>([])
const selectedSeriesId = ref('')
const volumeData = ref<VolumeData | null>(null)
const autoRotate = ref(false)

// 切片位置
const currentSlices = ref({
  axial: 0,
  coronal: 0,
  sagittal: 0
})

// 交互状态
const isMouseDown = ref(false)
const lastMousePos = ref({ x: 0, y: 0 })

// Canvas和容器引用
const axialCanvas = ref<HTMLCanvasElement>()
const coronalCanvas = ref<HTMLCanvasElement>()
const sagittalCanvas = ref<HTMLCanvasElement>()
const vtkViewport = ref<HTMLDivElement>()

// VTK相关对象（已禁用）
// let vtkRenderWindowObj: any = null
// let vtkRendererObj: any = null
// let vtkOpenGLRenderWindowObj: any = null
// let vtkInteractor: any = null
// let vtkVolumeActor: any = null
let rotationTimer: any = null

// ==================== 初始化和连接 ====================
const testConnection = async () => {
  try {
    orthancConnected.value = await orthancService.testConnection()
  } catch (error) {
    console.error('连接测试失败:', error)
    orthancConnected.value = false
  }
}

// 加载可用系列
const loadAvailableSeries = async () => {
  try {
    const studies = await orthancService.getStudies()
    const allSeries = []
    
    for (const study of studies) {
      for (const seriesId of study.Series || []) {
        try {
          const response = await fetch(`/api/orthanc/series/${seriesId}`)
          const seriesData = await response.json()
          
          // 只显示有足够切片数的系列（适合体数据）
          if (seriesData.Instances && seriesData.Instances.length >= 10) {
            allSeries.push({
              id: seriesId,
              ...seriesData
            })
          }
        } catch (error) {
          console.warn(`获取系列失败: ${seriesId}`)
        }
      }
    }
    
    availableSeries.value = allSeries
    console.log(`✅ 加载了 ${allSeries.length} 个适合的系列`)
  } catch (error) {
    console.error('加载系列列表失败:', error)
  }
}

// ==================== 体数据加载 ====================
const loadVolumeData = async () => {
  if (!selectedSeriesId.value) {
    alert('请先选择一个系列')
    return
  }
  
  loading.value = true
  loadProgress.value = 0
  loadingStatus.value = '准备加载...'
  
  try {
    console.log(`📥 开始加载体数据: ${selectedSeriesId.value}`)
    
    // 获取系列信息
    loadingStatus.value = '获取系列信息...'
    const response = await fetch(`/api/orthanc/series/${selectedSeriesId.value}`)
    const seriesData = await response.json()
    
    const instances = seriesData.Instances || []
    console.log(`找到 ${instances.length} 个实例`)
    
    // 第一步：并发获取所有实例的元数据并按Z轴排序
    loadingStatus.value = '获取元数据并排序...'
    
    console.log('📥 第1步：并发获取实例元数据...')
    console.time('⏱️ 元数据加载耗时')
    
    // 使用Promise.all并发获取所有元数据
    const metadataPromises = instances.map((instanceId: string, index: number) => 
      fetch(`/api/orthanc/instances/${instanceId}/simplified-tags`)
        .then(res => res.json())
        .then(tags => {
          // 更新进度
          loadProgress.value = Math.round(((index + 1) / instances.length) * 20)
          
          // 获取实例编号
          const instanceNumber = tags.InstanceNumber ? parseInt(tags.InstanceNumber) : index
          
          // 获取图像位置（用于排序）
          let imagePosition = [0, 0, 0]
          if (tags.ImagePositionPatient) {
            imagePosition = tags.ImagePositionPatient.split('\\').map(parseFloat)
          }
          
          // 获取切片位置
          const sliceLocation = tags.SliceLocation ? parseFloat(tags.SliceLocation) : 0
          
          return {
            id: instanceId,
            instanceNumber,
            imagePosition,
            sliceLocation,
            tags  // 缓存tags，后续可以复用
          }
        })
        .catch(() => {
          console.warn(`⚠️ 无法获取实例 ${instanceId} 的元数据，使用默认值`)
          return {
            id: instanceId,
            instanceNumber: index,
            imagePosition: [0, 0, index],
            sliceLocation: index,
            tags: null
          }
        })
    )
    
    const instanceInfos = await Promise.all(metadataPromises)
    console.timeEnd('⏱️ 元数据加载耗时')
    console.log(`✅ 并发加载了 ${instanceInfos.length} 个实例的元数据`)
    
    // 按Z轴位置排序
    instanceInfos.sort((a, b) => {
      // 优先使用图像位置的Z坐标
      if (a.imagePosition[2] !== b.imagePosition[2]) {
        return a.imagePosition[2] - b.imagePosition[2]
      }
      // 其次使用切片位置
      if (a.sliceLocation !== b.sliceLocation) {
        return a.sliceLocation - b.sliceLocation
      }
      // 最后使用实例编号
      return a.instanceNumber - b.instanceNumber
    })
    
    console.log('✅ 实例已按空间位置排序')
    console.log(`   首切片位置: ${instanceInfos[0].imagePosition[2].toFixed(2)}`)
    console.log(`   末切片位置: ${instanceInfos[instanceInfos.length - 1].imagePosition[2].toFixed(2)}`)
    
    // 第二步：智能并发加载图像数据
    console.log('📥 第2步：智能并发加载图像数据...')
    console.time('⏱️ 图像加载耗时')
    
    let firstImageObj: any = null
    let spacing = [1, 1, 1]
    const _origin = instanceInfos[0].imagePosition
    
    // 提前计算spacing（使用第一个实例的缓存tags）
    const firstInstanceInfo = instanceInfos[0]
    
    if (firstInstanceInfo.tags) {
      const tags = firstInstanceInfo.tags
      
      // 获取像素间距
      if (tags.PixelSpacing) {
        const pixelSpacing = tags.PixelSpacing.split('\\').map(parseFloat)
        spacing[0] = pixelSpacing[0] || 1
        spacing[1] = pixelSpacing[1] || 1
      }
      
      // 计算切片间距（使用相邻切片的位置差）
      if (instanceInfos.length > 1) {
        const sliceDiff = Math.abs(
          instanceInfos[1].imagePosition[2] - instanceInfos[0].imagePosition[2]
        )
        if (sliceDiff > 0) {
          spacing[2] = sliceDiff
        } else if (tags.SliceThickness) {
          spacing[2] = parseFloat(tags.SliceThickness)
        }
      } else if (tags.SliceThickness) {
        spacing[2] = parseFloat(tags.SliceThickness)
      }
      
      console.log(`📐 像素间距: [${spacing[0].toFixed(2)}, ${spacing[1].toFixed(2)}, ${spacing[2].toFixed(2)}] mm`)
    }
    
    // 根据切片数量动态调整并发数
    const optimalConcurrency = instanceInfos.length < 50 ? 10 : 8
    console.log(`🔧 使用并发数: ${optimalConcurrency}`)
    
    // 图像加载函数
    const loadSingleImage = async (instanceInfo: any, index: number) => {
      const instanceId = instanceInfo.id
      
      try {
        // 获取实例的预览图像
        const imgResponse = await fetch(`/api/orthanc/instances/${instanceId}/preview`)
        const imgBlob = await imgResponse.blob()
        const imgUrl = URL.createObjectURL(imgBlob)
        
        // 加载图像
        const img = await loadImage(imgUrl)
        
        if (index === 0) {
          firstImageObj = img
        }
        
        // 将图像转换为 ImageData
        const canvas = document.createElement('canvas')
        canvas.width = img.width
        canvas.height = img.height
        const ctx = canvas.getContext('2d')!
        ctx.drawImage(img, 0, 0)
        const imageData = ctx.getImageData(0, 0, img.width, img.height)
        
        // 提取灰度值（用于VTK）
        const grayscaleData = new Uint8Array(img.width * img.height)
        for (let j = 0; j < imageData.data.length; j += 4) {
          grayscaleData[j / 4] = imageData.data[j]
        }
        
        // 清理临时URL
        URL.revokeObjectURL(imgUrl)
        
        return { imageData, grayscaleData }
      } catch (error) {
        console.error(`❌ 加载实例失败 ${instanceId}:`, error)
        throw error
      }
    }
    
    // 使用并发池加载所有图像
    loadingStatus.value = '并发加载图像...'
    let completedCount = 0
    const imageDataArray: ImageData[] = []
    const slicesData: Uint8Array[] = []
    
    const results = await promisePool(
      instanceInfos,
      async (instanceInfo, index) => {
        const result = await loadSingleImage(instanceInfo, index)
        completedCount++
        loadProgress.value = 20 + Math.round((completedCount / instanceInfos.length) * 70)
        loadingStatus.value = `加载图像 ${completedCount}/${instanceInfos.length}`
        return result
      },
      optimalConcurrency
    )
    
    // 提取结果
    for (const result of results) {
      if (result) {
        imageDataArray.push(result.imageData)
        slicesData.push(result.grayscaleData)
      }
    }
    
    console.timeEnd('⏱️ 图像加载耗时')
    let totalSize = imageDataArray.reduce((sum, img) => sum + img.data.length, 0)
    
    if (imageDataArray.length === 0) {
      throw new Error('没有成功加载任何图像')
    }
    
    // 构建体数据
    loadingStatus.value = '构建体数据...'
    loadProgress.value = 95
    
    const [width, height, depth] = [firstImageObj.width, firstImageObj.height, imageDataArray.length]
    
    // 合并所有切片数据为单个数组（用于VTK）
    const scalarData = new Uint8Array(width * height * depth)
    for (let z = 0; z < depth; z++) {
      scalarData.set(slicesData[z], z * width * height)
    }
    
    volumeData.value = {
      dimensions: [width, height, depth],
      spacing: [1.0, 1.0, 1.0], // 默认间距
      origin: [0, 0, 0],
      slices: depth,
      totalSize,
      imageData: imageDataArray,
      scalarData: scalarData
    }
    
    // 初始化切片位置
    currentSlices.value = {
      axial: Math.floor(depth / 2),
      coronal: Math.floor(height / 2),
      sagittal: Math.floor(width / 2)
    }
    
    console.log(`✅ 体数据加载完成:`, volumeData.value.dimensions)
    
    // 渲染所有视图
    loadingStatus.value = '渲染视图...'
    loadProgress.value = 100
    await nextTick()
    
    renderAllViews()
    
    // 延迟初始化VTK 3D视图，确保DOM完全准备好
    setTimeout(() => {
      init3DView()
    }, 100)
    
  } catch (error) {
    console.error('加载体数据失败:', error)
    alert(`加载体数据失败: ${error}`)
  } finally {
    loading.value = false
    loadProgress.value = 0
    loadingStatus.value = ''
  }
}

// ==================== MPR视图渲染 ====================
const renderAllViews = () => {
  if (!volumeData.value) return
  renderAxialView()
  renderCoronalView()
  renderSagittalView()
}

// 渲染轴位视图（Z轴切片）
const renderAxialView = () => {
  if (!volumeData.value || !axialCanvas.value) return
  
  const canvas = axialCanvas.value
  const ctx = canvas.getContext('2d')!
  const sliceIndex = currentSlices.value.axial
  
  if (sliceIndex < volumeData.value.imageData.length) {
    const imageData = volumeData.value.imageData[sliceIndex]
    canvas.width = imageData.width
    canvas.height = imageData.height
    ctx.putImageData(imageData, 0, 0)
  }
}

// 渲染冠状视图（Y轴切片）
const renderCoronalView = () => {
  if (!volumeData.value || !coronalCanvas.value) return
  
  const canvas = coronalCanvas.value
  const ctx = canvas.getContext('2d')!
  const y = currentSlices.value.coronal
  
  const [width, , depth] = volumeData.value.dimensions
  const coronalImageData = ctx.createImageData(width, depth)
  
  // 从体数据中提取冠状切片（反向遍历以正确显示）
  for (let z = 0; z < depth; z++) {
    const sliceData = volumeData.value.imageData[depth - 1 - z]  // 反向读取
    if (sliceData && sliceData.data) {
      for (let x = 0; x < width; x++) {
        const srcIndex = (y * width + x) * 4
        const dstIndex = (z * width + x) * 4
        
        coronalImageData.data[dstIndex] = sliceData.data[srcIndex]
        coronalImageData.data[dstIndex + 1] = sliceData.data[srcIndex + 1]
        coronalImageData.data[dstIndex + 2] = sliceData.data[srcIndex + 2]
        coronalImageData.data[dstIndex + 3] = sliceData.data[srcIndex + 3]
      }
    } else {
      // 切片未加载时填充黑色，避免透明条纹
      for (let x = 0; x < width; x++) {
        const dstIndex = (z * width + x) * 4
        coronalImageData.data[dstIndex] = 0
        coronalImageData.data[dstIndex + 1] = 0
        coronalImageData.data[dstIndex + 2] = 0
        coronalImageData.data[dstIndex + 3] = 255
      }
    }
  }
  
  canvas.width = width
  canvas.height = depth
  ctx.putImageData(coronalImageData, 0, 0)
}

// 渲染矢状视图（X轴切片）
const renderSagittalView = () => {
  if (!volumeData.value || !sagittalCanvas.value) return
  
  const canvas = sagittalCanvas.value
  const ctx = canvas.getContext('2d')!
  const x = currentSlices.value.sagittal
  
  const [width, height, depth] = volumeData.value.dimensions
  const sagittalImageData = ctx.createImageData(height, depth)
  
  // 从体数据中提取矢状切片（反向遍历以正确显示）
  for (let z = 0; z < depth; z++) {
    const sliceData = volumeData.value.imageData[depth - 1 - z]  // 反向读取
    if (sliceData && sliceData.data) {
      for (let y = 0; y < height; y++) {
        const srcIndex = (y * width + x) * 4
        const dstIndex = (z * height + y) * 4
        
        sagittalImageData.data[dstIndex] = sliceData.data[srcIndex]
        sagittalImageData.data[dstIndex + 1] = sliceData.data[srcIndex + 1]
        sagittalImageData.data[dstIndex + 2] = sliceData.data[srcIndex + 2]
        sagittalImageData.data[dstIndex + 3] = sliceData.data[srcIndex + 3]
      }
    } else {
      // 切片未加载时填充黑色，避免透明条纹
      for (let y = 0; y < height; y++) {
        const dstIndex = (z * height + y) * 4
        sagittalImageData.data[dstIndex] = 0
        sagittalImageData.data[dstIndex + 1] = 0
        sagittalImageData.data[dstIndex + 2] = 0
        sagittalImageData.data[dstIndex + 3] = 255
      }
    }
  }
  
  canvas.width = height
  canvas.height = depth
  ctx.putImageData(sagittalImageData, 0, 0)
}

// ==================== VTK 3D视图 ====================
const init3DView = () => {
  console.warn('⚠️ VTK.js 功能已禁用：由于浏览器兼容性问题，vtk.js 依赖已从项目中移除')
  console.info('💡 建议使用 Cornerstone3D 的原生 Volume 渲染功能替代')
  return
  
  /* VTK.js 代码已禁用
  if (!volumeData.value || !vtkViewport.value) {
    console.warn('⚠️ 体数据或容器未准备好')
    return
  }

  try {
    // 1. 容器尺寸校验
    const rect = vtkViewport.value.getBoundingClientRect()
    if (rect.width === 0 || rect.height === 0) {
      setTimeout(init3DView, 200)
      return
    }

    // 2. 旧实例清理
    if (vtkRenderWindowObj) {
      try {
        vtkInteractor?.delete()
        vtkOpenGLRenderWindowObj?.delete()
        vtkRenderWindowObj?.delete()
      } catch (e) {
        console.warn('清理旧渲染器时出错:', e)
      }
      vtkRenderWindowObj = vtkRendererObj = vtkOpenGLRenderWindowObj = vtkInteractor = vtkVolumeActor = null
    }
    vtkViewport.value.innerHTML = ''

    // 3. 创建基础对象
    vtkRenderWindowObj = vtkRenderWindow.newInstance()
    vtkRendererObj      = vtkRenderer.newInstance({ background: [0.1, 0.1, 0.1] })
    vtkRenderWindowObj.addRenderer(vtkRendererObj)

    vtkOpenGLRenderWindowObj = vtkOpenGLRenderWindow.newInstance()
    vtkOpenGLRenderWindowObj.setContainer(vtkViewport.value)
    vtkRenderWindowObj.addView(vtkOpenGLRenderWindowObj)
    vtkOpenGLRenderWindowObj.setSize(Math.floor(rect.width), Math.floor(rect.height))

    vtkInteractor = vtkRenderWindowInteractor.newInstance()
    // 先设置交互样式，再设置视图，最后初始化
    vtkInteractor.setInteractorStyle(
      vtkInteractorStyleTrackballCamera.newInstance()
    )
    vtkInteractor.setView(vtkOpenGLRenderWindowObj)
    vtkInteractor.initialize()              // 初始化后内部会触发一次 render
    vtkInteractor.bindEvents(vtkViewport.value)

    // 4. 创建 ImageData → mapper → volume
    const imageData = vtkImageData.newInstance()
    const [w, h, d] = volumeData.value.dimensions
    imageData.setDimensions(w, h, d)
    imageData.setSpacing(volumeData.value.spacing)
    imageData.setOrigin(volumeData.value.origin)
    imageData.getPointData().setScalars(
      vtkDataArray.newInstance({
        name: 'Scalars',
        values: volumeData.value.scalarData,
        numberOfComponents: 1
      })
    )

    const mapper = vtkVolumeMapper.newInstance()
    mapper.setInputData(imageData)

    vtkVolumeActor = vtkVolume.newInstance()
    vtkVolumeActor.setMapper(mapper)

    // 5. 简单颜色/不透明度
    const ctfun = vtkColorTransferFunction.newInstance()
    ctfun.addRGBPoint(0, 0, 0, 0)
    ctfun.addRGBPoint(255, 1, 1, 1)
    const ofun = vtkPiecewiseFunction.newInstance()
    ofun.addPoint(0, 0)
    ofun.addPoint(255, 1)
    vtkVolumeActor.getProperty().setRGBTransferFunction(0, ctfun)
    vtkVolumeActor.getProperty().setScalarOpacity(0, ofun)

    vtkRendererObj.addVolume(vtkVolumeActor)
    vtkRendererObj.resetCamera()

    // 6. 最终渲染
    vtkRenderWindowObj.render()
  } catch (err) {
    console.error('VTK 3D视图初始化失败:', err)
  }
  */ // VTK.js 代码已禁用结束
}

const reset3DView = () => {
  console.warn('⚠️ VTK.js 功能已禁用')
  return
  /* VTK.js 代码已禁用
  if (vtkRendererObj && vtkRenderWindowObj) {
    vtkRendererObj.resetCamera()
    vtkRenderWindowObj.render()
  }
  */
}

const toggle3DRotation = () => {
  console.warn('⚠️ VTK.js 功能已禁用')
  return
  /* VTK.js 代码已禁用
  autoRotate.value = !autoRotate.value
  
  if (autoRotate.value) {
    rotationTimer = setInterval(() => {
      if (!vtkRendererObj || !vtkRenderWindowObj) return
      
      const camera = vtkRendererObj.getActiveCamera()
      camera.azimuth(1)
      vtkRenderWindowObj.render()
    }, 50)
  } else {
    if (rotationTimer) {
      clearInterval(rotationTimer)
      rotationTimer = null
    }
  }
  */
}

// ==================== 交互事件处理 ====================
const onMouseDown = (event: MouseEvent) => {
  isMouseDown.value = true
  lastMousePos.value = { x: event.clientX, y: event.clientY }
}

const onMouseMove = (_view: string, event: MouseEvent) => {
  if (!isMouseDown.value) return
  
  // 可以根据需要实现窗宽窗位调整等功能
  lastMousePos.value = { x: event.clientX, y: event.clientY }
}

const onMouseUp = (_event: MouseEvent) => {
  isMouseDown.value = false
}

const onWheel = (view: string, event: WheelEvent) => {
  if (!volumeData.value) return
  
  const delta = event.deltaY > 0 ? 1 : -1
  
  // 根据视图切换切片
  if (view === 'axial') {
    currentSlices.value.axial = Math.max(0, Math.min(
      volumeData.value.dimensions[2] - 1,
      currentSlices.value.axial + delta
    ))
  } else if (view === 'coronal') {
    currentSlices.value.coronal = Math.max(0, Math.min(
      volumeData.value.dimensions[1] - 1,
      currentSlices.value.coronal + delta
    ))
  } else if (view === 'sagittal') {
    currentSlices.value.sagittal = Math.max(0, Math.min(
      volumeData.value.dimensions[0] - 1,
      currentSlices.value.sagittal + delta
    ))
  }
}

const resetAllViews = () => {
  if (!volumeData.value) return
  
  currentSlices.value = {
    axial: Math.floor(volumeData.value.dimensions[2] / 2),
    coronal: Math.floor(volumeData.value.dimensions[1] / 2),
    sagittal: Math.floor(volumeData.value.dimensions[0] / 2)
  }
  
  renderAllViews()
  reset3DView()
}

// ==================== 辅助函数 ====================
// 辅助函数：加载图像
const loadImage = (url: string): Promise<HTMLImageElement> => {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.onload = () => resolve(img)
    img.onerror = reject
    img.src = url
  })
}

// 辅助函数：智能并发池控制
const promisePool = async <T, R>(
  items: T[],
  asyncFn: (item: T, index: number) => Promise<R>,
  concurrency: number = 8
): Promise<R[]> => {
  const results: R[] = new Array(items.length)
  let index = 0
  
  // 工作函数：处理单个任务
  const worker = async (): Promise<void> => {
    while (index < items.length) {
      const currentIndex = index++
      try {
        results[currentIndex] = await asyncFn(items[currentIndex], currentIndex)
      } catch (error) {
        console.error(`Task ${currentIndex} failed:`, error)
        // 继续处理下一个，不中断整个流程
      }
    }
  }
  
  // 创建并发工作池
  const workers = Array(Math.min(concurrency, items.length))
    .fill(null)
    .map(() => worker())
  
  await Promise.all(workers)
  return results
}

const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// ==================== 监听器 ====================
watch(currentSlices, () => {
  renderAllViews()
}, { deep: true })

// ==================== 生命周期 ====================
onMounted(async () => {
  console.log('🚀 初始化体数据加载页面（MPR + VTK 3D）')
  
  await testConnection()
  
  if (orthancConnected.value) {
    await loadAvailableSeries()
  }
})

onBeforeUnmount(() => {
  // 清理VTK资源
  if (rotationTimer) {
    clearInterval(rotationTimer)
  }
  if (vtkInteractor) {
    vtkInteractor.delete()
  }
  if (vtkOpenGLRenderWindowObj) {
    vtkOpenGLRenderWindowObj.delete()
  }
  if (vtkRenderWindowObj) {
    vtkRenderWindowObj.delete()
  }
})
</script>

<style scoped>
.dicom-volume-page {
  height: 100%;
  width: 100%;
  background: #1a1a1a;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* ==================== 工具栏 ==================== */
.toolbar {
  height: 60px;
  background: #2d2d2d;
  border-bottom: 1px solid #404040;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  flex-shrink: 0;
  gap: 15px;
}

.toolbar-left {
  display: flex;
  align-items: center;
}

.page-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #ffffff;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 15px;
  flex: 1;
  justify-content: flex-end;
}

.connection-status {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 6px;
  font-size: 14px;
}

.status-indicator {
  font-size: 12px;
}

.status-text {
  color: #b0b0b0;
}

.volume-info {
  display: flex;
  gap: 12px;
  padding: 6px 12px;
  background: rgba(59, 130, 246, 0.1);
  border-radius: 6px;
  font-size: 13px;
}

.info-item {
  color: #60a5fa;
  font-weight: 500;
}

.series-select-toolbar {
  min-width: 250px;
  padding: 8px 12px;
  border: 1px solid #404040;
  border-radius: 6px;
  background: #1a1a1a;
  color: #ffffff;
  font-size: 14px;
  cursor: pointer;
}

.series-select-toolbar:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.load-btn,
.reset-btn {
  padding: 8px 16px;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.load-btn {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.load-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.load-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.reset-btn {
  background: #404040;
  color: #ffffff;
}

.reset-btn:hover:not(:disabled) {
  background: #4a4a4a;
}

.reset-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ==================== 进度条 ==================== */
.load-progress-bar {
  height: 10px;
  background: #2d2d2d;
  position: relative;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #667eea, #764ba2);
  transition: width 0.3s ease;
}

.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 11px;
  color: #ffffff;
  font-weight: 500;
  white-space: nowrap;
  pointer-events: none;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

/* ==================== 主内容区域 ==================== */
.main-content {
  flex: 1;
  display: flex;
  overflow: hidden;
  position: relative;
}

.empty-viewer {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #1a1a1a;
}

.empty-content {
  text-align: center;
}

.empty-icon {
  font-size: 80px;
  margin-bottom: 20px;
  opacity: 0.3;
}

.empty-title {
  font-size: 24px;
  font-weight: 600;
  color: #ffffff;
  margin-bottom: 10px;
}

.empty-subtitle {
  font-size: 14px;
  color: #888888;
}

/* ==================== 四宫格布局 ==================== */
.four-view-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 2px;
  background: #404040;
  width: 100%;
  height: 100%;
}

.viewport {
  background: #1a1a1a;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}

.viewport-header {
  height: 40px;
  padding: 0 12px;
  background: #2d2d2d;
  border-bottom: 1px solid #404040;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
}

.viewport-header h4 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #ffffff;
}

.slice-info {
  font-size: 12px;
  color: #888888;
  font-weight: 500;
}

.view-controls {
  display: flex;
  gap: 8px;
}

.control-btn {
  padding: 4px 10px;
  border: 1px solid #404040;
  border-radius: 4px;
  background: #1a1a1a;
  color: #b0b0b0;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;
}

.control-btn:hover {
  background: #2d2d2d;
  color: #ffffff;
  border-color: #505050;
}

.control-btn.active {
  background: #667eea;
  color: white;
  border-color: #667eea;
}

.viewport-content {
  flex: 1;
  position: relative;
  background: #000000;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.dicom-canvas {
  max-width: 100%;
  max-height: 100%;
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
}

.viewport-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 10;
}

.orientation-labels {
  position: relative;
  width: 100%;
  height: 100%;
}

.orientation-labels span {
  position: absolute;
  color: #00ff00;
  font-size: 14px;
  font-weight: bold;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.9);
  padding: 4px;
}

.label-top {
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
}

.label-bottom {
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
}

.label-left {
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
}

.label-right {
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}

/* ==================== 切片滑块 ==================== */
.slice-slider-container {
  height: 30px;
  padding: 0 12px;
  background: #2d2d2d;
  border-top: 1px solid #404040;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.slice-slider {
  width: 100%;
  height: 4px;
  border-radius: 2px;
  background: #404040;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}

.slice-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #667eea;
  cursor: pointer;
  transition: all 0.2s;
}

.slice-slider::-webkit-slider-thumb:hover {
  background: #764ba2;
  transform: scale(1.2);
}

.slice-slider::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #667eea;
  cursor: pointer;
  border: none;
  transition: all 0.2s;
}

.slice-slider::-moz-range-thumb:hover {
  background: #764ba2;
  transform: scale(1.2);
}

/* ==================== VTK 3D视图特殊样式 ==================== */
.vtk-3d-view .viewport-content {
  background: #0a0a0a;
}

/* 确保VTK容器正确填充 */
.vtk-3d-view .viewport-content > div {
  width: 100% !important;
  height: 100% !important;
}

/* ==================== 响应式 ==================== */
@media (max-width: 1200px) {
  .toolbar {
    padding: 0 15px;
  }
  
  .series-select-toolbar {
    min-width: 180px;
  }
}
</style>


